package com.wang.service.impl;
import com.wang.constant.CacheKey;
import com.wang.service.NotifyService;
import com.wang.enums.BizCodeEnum;
import com.wang.enums.SendCodeEnum;
import com.wang.component.MailService;
import com.wang.util.CheckUtil;
import com.wang.util.CommonUtil;
import com.wang.util.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class NotifyServiceImpl implements NotifyService {
   //验证码的标题
    private static final String SUBJECT = "验证码";

    //验证码的内容
    private static final String CONTENT = "您的验证码是：%s,有效时间是10分钟,这个验证码一定不要告诉别人哦！";

    //10分钟   设置超时时间
    private static final int CODE_EXPIRED = 60 * 1000 * 10;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    MailService mailService;

    /**
     * 前置：判断是否是重复发送
     *      1.存储验证码到缓存中
     *      2.发送邮箱验证码
     * 后置：存储发送记录
     *
     * @param sendCodeType
     * @param to   信息接收者
     * @return
     */
    @Override
    public JsonData sendCode(SendCodeEnum sendCodeType, String to) {

        //将发送类型和接收者拼接成key   这里的String.format()用来替换字符串中的占位符
        //第一个参数是进行替换操作的字符串，第二个参数是要替换的第一个参数，第三个参数是替换的第二个参数
        String cacheKey = String.format(CacheKey.CHECK_CODE_KEY,SendCodeEnum.USER_REGISTER.name(),to);

        //从redis中获取对应的value
        String cacheValue = (String)redisTemplate.opsForValue().get(cacheKey);


        //判断是否为空，如果不为空，则判断是否是60秒内重复发送
        if(StringUtils.isNotBlank(cacheValue)){
            //获取当前时间戳，如果小于60秒，则不给重复发送
            long ttl = Long.parseLong(cacheValue.split("_")[1]);
            if(CommonUtil.getCurrentTimesTamp() - ttl < 1000*60){
                log.info("验证码已经发送，请勿重复发送");
                return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
            }
        }

        //拼接验证码    随机数_时间戳
        String code = CommonUtil.getRandomCode(6);

        String value = code + "_" + CommonUtil.getCurrentTimesTamp();

        //这里的过期时间设置为10分钟，方便等会的测试（不直接设置为1分钟怕等会超时，后面可以改过来）    时间单位是毫秒
        redisTemplate.opsForValue().set(cacheKey,value,CODE_EXPIRED, TimeUnit.MILLISECONDS);


        if(CheckUtil.isEmail(to)){
            //发送邮箱验证码给用户
            mailService.sendSimpleMail(to,SUBJECT, String.format(CONTENT,code));
            return JsonData.buildSuccess();

        }else if(CheckUtil.isPhone(to)){
            //短信验证码
        }

        return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);
    }

    /**
     * 邮箱验证码校验
     * @param sendCodeType
     * @param to
     * @param code
     * @return
     */
    public boolean checkCode(SendCodeEnum sendCodeType, String to,String code) {
        String cacheKey = String.format(CacheKey.CHECK_CODE_KEY,sendCodeType.name(),to);

        Object cacheObj = redisTemplate.opsForValue().get(cacheKey);
        if (cacheObj == null) {
            return false;
        }
        String cacheValue = (String)cacheObj;

        if(StringUtils.isNotBlank(cacheKey)){
            String cacheCode = cacheValue.split("_")[0];
            if (cacheCode.equals(code)){
                //删除验证码
                redisTemplate.delete(cacheKey);
                return true;
            }
        }
        return false;
    }
}
